package com.ushahidi.android.app;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Vector;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.ushahidi.android.app.data.AddIncidentData;
import com.ushahidi.android.app.data.UshahidiDatabase;
import com.ushahidi.android.app.net.UshahidiHttpClient;
import com.ushahidi.android.app.util.Util;

public class IProvide extends DashboardActivity
{

    /**
     * category that exists on the phone before any connection to a server, at
     * present it is trusted reporter, id number 4 but will change to specific
     * 'uncategorized' category when it is ready on the server
     */
    private static final String       UNCATEGORIZED_CATEGORY_ID    = "4";

    private static final String       UNCATEGORIZED_CATEGORY_TITLE = "uncategorized";

    // Menu Numbers

    private static final int          HOME                         = Menu.FIRST + 1;

    private static final int          LIST_INCIDENT                = Menu.FIRST + 2;

    private static final int          INCIDENT_MAP                 = Menu.FIRST + 3;

    private static final int          INCIDENT_REFRESH             = Menu.FIRST + 4;

    private static final int          SETTINGS                     = Menu.FIRST + 5;

    private static final int          ABOUT                        = Menu.FIRST + 6;

    // Intent Mark

    private static final int          GOTOHOME                     = 0;

    private static final int          MAP_INCIDENTS                = 1;

    private static final int          LIST_INCIDENTS               = 2;

    private static final int          REQUEST_CODE_SETTINGS        = 2;

    private static final int          REQUEST_CODE_ABOUT           = 3;

    private static final int          REQUEST_CODE_IMAGE           = 4;

    private static final int          REQUEST_CODE_CAMERA          = 5;

    // ------------------
    private static final int          REQUEST_CODE_CHANGE_LOC      = 6;
    // -----------------------
    //

    private static final int          VIEW_MAP                     = 1;

    private static final int          VIEW_SEARCH                  = 2;

    private Geocoder                  mGc;

    private List<Address>             mFoundAddresses;

    // date and time
    // keep unchanged just to make it easier to build time string..
    // can be replaced with format and date() if decided in future.
    private int                       mYear;

    private int                       mMonth;

    private int                       mDay;

    private int                       mHour;

    private int                       mMinute;

    private int                       mCounter                     = 0;

    private static double             sLongitude                   = 0.0;

    private static double             sLatitude                    = 0.0;

    private static double             currentLongitude             = 0.0;

    private static double             currentLatitude              = 0.0;

    private String                    sLocationName                = "Current Location";

    private String                    CurrLocation                 = "Current Location";

    private String                    mErrorMessage                = "";

    private String                    mDateToSubmit                = "";

    // File used to store picture
    private String                    mFilename                    = "";
    // Whether ready to send
    private boolean                   mError                       = false;

    // ========================================
    // = Component Starts =
    // ========================================
    private EditText                  mIncidentTitle;

    private EditText                  mIncidentLocation;

    private EditText                  mIncidentDesc;

    private TextView                  mIncidentDate;

    private ImageView                 mSelectedPhoto;

    private TextView                  mSelectedCategories;

    private TextView                  mReportLocation;
    
    private TextView                  mContactInformation;    

    private TextView                  activityTitle;

    private Button                    mBtnSend;

    private Button                    mBtnCancel;

    private Button                    mBtnAddCategory;

    private Button                    findButton;

    // private Button mPickTime;

    // private Button mPickDate;

    private Button                    mBtnPicture;

    private HashMap<Integer, Integer> mTimeDigits;

    private Bundle                    mBundle;

    private Bundle                    mExtras;

    private MapView                   mapView                      = null;

    private MapController             mapController;

    // ========================================
    // = Dialogs =
    // ========================================

    private static final int          DIALOG_ERROR_NETWORK         = 0;

    private static final int          DIALOG_ERROR_SAVING          = 1;

    private static final int          DIALOG_CHOOSE_IMAGE_METHOD   = 2;

    private static final int          DIALOG_MULTIPLE_CATEGORY     = 3;

    private static final int          TIME_DIALOG_ID               = 4;

    private static final int          DATE_DIALOG_ID               = 5;

    private final static Handler      mHandler                     = new Handler();

    // ========================================
    // = CategoriesStore =
    // ========================================

    private Vector<String>            mVectorCategories            = new Vector<String>();
    // store selected category_ids

    private Vector<String>            mCategoriesId                = new Vector<String>();
    // list catagory_ids by order in menu

    private HashMap<String, String>   mCategoriesTitle             = new HashMap<String, String>();
    // category_id -> category_name

    private HashMap<String, String>   mParams                      = new HashMap<String, String>();

    // for temporary use

    // =======================================
    // = =
    // = TODO KEY LIFE CYCLE =
    // = =
    // =======================================
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
	super.onCreate(savedInstanceState);
	requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
	setContentView(R.layout.i_provide);
	if (this.getIntent().getExtras() != null
	        && this.getIntent().getExtras().containsKey("InID"))
	    UshahidiPref.IncidentID2Link = getIntent().getExtras().getInt(
		    "InID")
		    + "";
	else
	    UshahidiPref.IncidentID2Link = ""; // reset IncidentID2Link so as to
					       // stop sent link request
	mFoundAddresses = new ArrayList<Address>();

	mGc = new Geocoder(this, Locale.US);
	// TODO OceanMaster, change this when internationalized.

	// load settings
	UshahidiPref.loadSettings(IProvide.this);

	initComponents();

	// configureMap();
	readyLocationService();
	// make sure current location and pick right detail level

    }

    @Override
    protected void onDestroy()
    {
	// house keeping
	// ((LocationManager) getSystemService(Context.LOCATION_SERVICE))
	// .removeUpdates(new DeviceLocationListener());
	unregisterListeners();
	super.onDestroy();
    }

    /**
     * Any time we are paused we need to save away the current state, so it will
     * be restored correctly when we are resumed.
     */
    @Override
    protected void onPause()
    {
	// ((LocationManager) getSystemService(Context.LOCATION_SERVICE))
	// .removeUpdates(new DeviceLocationListener());
	unregisterListeners();

	SharedPreferences.Editor editor = getPreferences(0).edit();
	editor.putString("title", mIncidentTitle.getText().toString());
	editor.putString("desc", mIncidentDesc.getText().toString()); // TODO
								      // recovery
								      // when
								      // needed
	editor.putString("location", mIncidentLocation.getText().toString());
	editor.putString("contact", mContactInformation.getText().toString());
	
	editor.commit();
	super.onPause();
    }

    @Override
    protected void onStop()
    {
	super.onStop();
	// house keeping
	// ((LocationManager) getSystemService(Context.LOCATION_SERVICE))
	// .removeUpdates(new DeviceLocationListener());
	unregisterListeners();
    }

    /**
     * Upon being resumed we can retrieve the current state. This allows us to
     * update the state if it was changed at any time while paused.
     */
    @Override
    protected void onResume()
    {
	if (!TextUtils.isEmpty(UshahidiPref.resourceFileName))
	{
	    mBtnPicture.setText(getString(R.string.change_photo));
	}

	SharedPreferences prefs = getPreferences(0);
	String title = prefs.getString("title", null);
	String desc = prefs.getString("desc", null);
	String contact = prefs.getString("contact", null);
	
	if (title != null)
	    mIncidentTitle.setText(title, TextView.BufferType.EDITABLE);

	if (desc != null)
	    mIncidentDesc.setText(desc, TextView.BufferType.EDITABLE);

	if (contact != null)
	    mContactInformation.setText(contact, TextView.BufferType.EDITABLE);

	
	// Request updated location when resume
	registerHighOneTimeListener();

	super.onResume();
    }

    // =========================
    // = TODO Location Service =
    // =========================
    LocationManager                       manager;
    long                                  updateTimeMsec = 0;
    float                                 updateDistance = 0;
    LocationProvider                      high;
    LocationProvider                      low;

    private OneTimeDeviceLocationListener high_listener  = null;
    private OneTimeDeviceLocationListener low_listener   = null;

    private void registerHighOneTimeListener()
    {
	high_listener = new OneTimeDeviceLocationListener();
	manager.requestLocationUpdates(high.getName(), updateTimeMsec,
	        updateDistance, high_listener);
    }

    private void registerLowOneTimeListener()
    {
	low_listener = new OneTimeDeviceLocationListener();
	manager.requestLocationUpdates(low.getName(), updateTimeMsec,
	        updateDistance, low_listener);
    }

    private void unregisterListeners()
    {
	if (high_listener != null)
	{
	    manager.removeUpdates(high_listener);
	    high_listener = null;
	}
	if (low_listener != null)
	{
	    manager.removeUpdates(low_listener);
	    low_listener = null;
	}
    }

    // Fetches the current location of the device.
    // create two different listeners, one for once, one for long
    // temporarily, periodical location service is not needed because
    // we are not following user
    private void readyLocationService()
    {
	// ===============================
	// ready one time location request
	// ===============================
	// listener = new OneTimeDeviceLocationListener();
	manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

	// get low and high accuracy provider
	// this is tempararily changed, due to simulation
	// low = manager.getProvider(manager.getBestProvider(
	// Util.createCoarseCriteria(), true));
	// high = manager.getProvider(manager.getBestProvider(
	// Util.createFineCriteria(), true));

	low = manager.getProvider(manager.NETWORK_PROVIDER);
	high = manager.getProvider(manager.GPS_PROVIDER);

	// imediately register 2 one time service to update location
	registerHighOneTimeListener();
	registerLowOneTimeListener();
    }

    /*
     * Drawable marker; private void configureMap() { Log.v("Oceanmaster",
     * "Mapview BuiltInZoomControls On");
     * 
     * marker = getResources().getDrawable(R.drawable.marker);
     * marker.setBounds(0, 0, marker.getIntrinsicWidth(),
     * marker.getIntrinsicHeight());
     * 
     * mapView.getController().setZoom(16);//changed from 14 to 16
     * mapView.setBuiltInZoomControls(true);
     * //mapView.displayZoomControls(true); }
     */
    /*
     * private void placeMarker(int markerLatitude, int markerLongitude) {
     * //TODO switch marker icons //TODO Can we optimized this by directly
     * change exosting MapMarker. Not sure yet mapView.getOverlays().add( new
     * MapMarker(marker, markerLatitude, markerLongitude)); }
     */
    public GeoPoint getPoint(double lat, double lon)
    {
	return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
    }

    // Modified by OceanMaster, added updateText argument
    /*
     * private void centerLocation(GeoPoint centerGeoPoint, boolean updateText)
     * { mapController.animateTo(centerGeoPoint); sLatitude =
     * centerGeoPoint.getLatitudeE6() / 1.0E6; sLongitude =
     * centerGeoPoint.getLongitudeE6() / 1.0E6; if(updateText)
     * mIncidentLocation.setText(getLocationFromLatLon(sLatitude, sLongitude));
     * placeMarker(centerGeoPoint.getLatitudeE6(),
     * centerGeoPoint.getLongitudeE6()); }
     */
    /*
     * private void setLocationBySearch(String search) { Log.v("Oceanmaster",
     * "setLocationBySearch : "+search); if(search==null || search.length()==0)
     * { Util.showToast(IProvide.this,
     * "Please fill search field first to find location"); return; } try {
     * List<Address> result = mGc.getFromLocationName(search, 1);
     * if(result.size()<=0) { Util.showToast(IProvide.this,"No result found");
     * return; }
     * 
     * Address location = result.get(0);
     * 
     * sLatitude = location.getLatitude(); sLongitude = location.getLongitude();
     * 
     * centerLocation(getPoint(sLatitude, sLongitude),false);
     * mReportLocation.setText(String.valueOf(sLatitude) + ", " +
     * String.valueOf(sLongitude));
     * 
     * } catch (IOException e) { Util.showToast(IProvide.this,
     * "Error occured while trying to search Location"); } }
     */
    // get the real location name from the latitude and longitude.
    public String getLocationFromLatLon(double lat, double lon)
    {
	Log.v("Oceanmaster", "Location name service requested");
	try
	{

	    Address address;
	    mFoundAddresses = mGc.getFromLocation(lat, lon, 2);
	    if (mFoundAddresses.size() > 0)
	    {
		address = mFoundAddresses.get(0);
		return address.getSubAdminArea();
	    }
	    else
	    {
		return "";
	    }
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	}
	return "";
    }

    /*
     * @Override protected boolean isRouteDisplayed() { return false; }
     */

    /*
     * public class MapMarker extends ItemizedOverlay<OverlayItem> {
     * 
     * private List<OverlayItem> locations = new ArrayList<OverlayItem>();
     * 
     * private Drawable marker;
     * 
     * private OverlayItem myOverlayItem;
     * 
     * public MapMarker(Drawable defaultMarker, int LatitudeE6, int LongitudeE6)
     * { super(defaultMarker); this.marker = defaultMarker;
     * 
     * // create locations of interest GeoPoint myPlace = new
     * GeoPoint(LatitudeE6, LongitudeE6);
     * 
     * myOverlayItem = new OverlayItem(myPlace, " ", " ");
     * 
     * locations.add(myOverlayItem);
     * 
     * populate();
     * 
     * }
     * 
     * //Added by OceanMaster, not tested public void addLocation(int
     * LatitudeE6, int LongitudeE6) { GeoPoint myPlace = new
     * GeoPoint(LatitudeE6, LongitudeE6); myOverlayItem = new
     * OverlayItem(myPlace, " ", " "); locations.add(myOverlayItem); populate();
     * }
     * 
     * @Override protected OverlayItem createItem(int i) { return
     * locations.get(i); }
     * 
     * @Override public int size() { return locations.size(); }
     * 
     * @Override public void draw(Canvas canvas, MapView mapView, boolean
     * shadow) { super.draw(canvas, mapView, shadow); boundCenterBottom(marker);
     * } }
     */
    // get the current location of the device/user
    public class OneTimeDeviceLocationListener implements LocationListener
    {
	OneTimeDeviceLocationListener()
	{
	    super();
	    Log.v("Oceanmaster", "new OneTimeListener Created");
	}

	public void onLocationChanged(Location location)
	{
	    Log.v("Oceanmaster", "Location Changed");
	    if (location != null)
	    {
		manager.removeUpdates(OneTimeDeviceLocationListener.this);

		currentLatitude = location.getLatitude();
		currentLongitude = location.getLongitude();
		// sLatitude = currentLatitude;
		// sLongitude = currentLongitude;
		// sLocationName = "Current Location";
		if (sLocationName.equals("Current Location")
		        || sLocationName == "")
		{
		    sLocationName = "Current Location";
		    mIncidentLocation.setText(sLocationName);
		}

		Log.v("Oceanmaster", "current location is:" + "("
		        + currentLatitude + ", " + currentLongitude + ")");
		// centerLocation(getPoint(sLatitude, sLongitude),true);
		// mReportLocation.setText(String.valueOf(sLatitude) + ", "
		// + String.valueOf(sLongitude));
	    }
	}

	public void onProviderDisabled(String provider)
	{
	    Util.showToast(IProvide.this, R.string.location_not_found);
	    Log.v("Oceanmaster", "LocationProvider " + provider.toString()
		    + " Disabled");
	}

	public void onProviderEnabled(String provider)
	{
	    Log.v("Oceanmaster", "LocationProvider " + provider.toString()
		    + " Enabled");
	}

	public void onStatusChanged(String provider, int status, Bundle extras)
	{

	}
    }

    // ========================
    // = menu stuff =
    // ========================

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
	    ContextMenu.ContextMenuInfo menuInfo)
    {
	populateMenu(menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
	populateMenu(menu);

	return (super.onCreateOptionsMenu(menu));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {

	return (applyMenuChoice(item) || super.onOptionsItemSelected(item));
    }

    @Override
    public boolean onContextItemSelected(MenuItem item)
    {

	return (applyMenuChoice(item) || super.onContextItemSelected(item));
    }

    private void populateMenu(Menu menu)
    {
	// TODO save for later modify
	MenuItem i;

	i = menu.add(Menu.NONE, HOME, Menu.NONE, R.string.menu_home);
	i.setIcon(R.drawable.ushahidi_home);

	i = menu.add(Menu.NONE, LIST_INCIDENT, Menu.NONE,
	        R.string.incident_list);
	i.setIcon(R.drawable.ushahidi_list);

	i = menu.add(Menu.NONE, INCIDENT_MAP, Menu.NONE,
	        R.string.incident_menu_map);
	i.setIcon(R.drawable.ushahidi_map);

	i = menu.add(Menu.NONE, INCIDENT_REFRESH, Menu.NONE,
	        R.string.incident_menu_refresh);
	i.setIcon(R.drawable.ushahidi_refresh);

	i = menu.add(Menu.NONE, SETTINGS, Menu.NONE, R.string.menu_settings);
	i.setIcon(R.drawable.ushahidi_settings);

	i = menu.add(Menu.NONE, ABOUT, Menu.NONE, R.string.menu_about);
	i.setIcon(R.drawable.ushahidi_about);

    }

    private boolean applyMenuChoice(MenuItem item)
    {
	Intent launchPreferencesIntent;
	switch (item.getItemId())
	{

	    case LIST_INCIDENT:
		launchPreferencesIntent = new Intent(IProvide.this,
		        IProvide.class);
		startActivityForResult(launchPreferencesIntent, LIST_INCIDENTS);
		setResult(RESULT_OK);
		return true;

	    case INCIDENT_MAP:
		launchPreferencesIntent = new Intent(IProvide.this,
		        ListIncidents.class);
		startActivityForResult(launchPreferencesIntent, MAP_INCIDENTS);
		return true;

	    case HOME:
		launchPreferencesIntent = new Intent(IProvide.this,
		        Ushahidi.class);
		startActivityForResult(launchPreferencesIntent, GOTOHOME);
		setResult(RESULT_OK);
		return true;

	    case ABOUT:
		launchPreferencesIntent = new Intent(IProvide.this, About.class);
		startActivityForResult(launchPreferencesIntent,
		        REQUEST_CODE_ABOUT);
		setResult(RESULT_OK);
		return true;

	    case SETTINGS:
		launchPreferencesIntent = new Intent().setClass(IProvide.this,
		        Settings.class);

		// Make it a subactivity so we know when it returns
		startActivityForResult(launchPreferencesIntent,
		        REQUEST_CODE_SETTINGS);
		return true;

	}
	return false;
    }

    // ========================
    // = Init UI component =
    // ========================
    private void initComponents()
    {
	findButton = (Button) findViewById(R.id.find_button);

	mBtnPicture = (Button) findViewById(R.id.btnPicture);
	mBtnAddCategory = (Button) findViewById(R.id.add_category);
	mBtnSend = (Button) findViewById(R.id.incident_add_btn);
	mBtnCancel = (Button) findViewById(R.id.incident_add_cancel);
	// mIncidentDate = (TextView) findViewById(R.id.lbl_date);
	// mPickDate = (Button) findViewById(R.id.pick_date);
	// mPickTime = (Button) findViewById(R.id.pick_time);
	// mReportLocation = (TextView) findViewById(R.id.latlon);
	mSelectedPhoto = (ImageView) findViewById(R.id.sel_photo_prev);
	mSelectedCategories = (TextView) findViewById(R.id.lbl_category);
	activityTitle = (TextView) findViewById(R.id.title_text);
	if (activityTitle != null)
	    activityTitle.setText(getTitle());
	mIncidentTitle = (EditText) findViewById(R.id.incident_title);
	mIncidentLocation = (EditText) findViewById(R.id.incident_location);
	// mapView = (MapView) findViewById(R.id.location_map);
	// mapController = mapView.getController();
	mIncidentTitle
	        .setOnFocusChangeListener(new View.OnFocusChangeListener()
	        {

		    public void onFocusChange(View v, boolean hasFocus)
		    {
		        if (!hasFocus)
		        {
			    if (TextUtils.isEmpty(mIncidentTitle.getText()))
			    {
			        mIncidentTitle
			                .setError(getString(R.string.empty_report_title));
			    }
		        }

		    }

	        });

	mIncidentLocation
	        .setOnFocusChangeListener(new View.OnFocusChangeListener()
	        {

		    public void onFocusChange(View v, boolean hasFocus)
		    {
		        // Modified by OceanMaster, not required any more.
		        // if (!hasFocus)
		        // {
		        // if (TextUtils.isEmpty(mIncidentLocation.getText()))
		        // {
		        // mIncidentLocation
		        // .setError(getString(R.string.empty_report_location));
		        // }
		        // }
		    }
	        });

	mIncidentDesc = (EditText) findViewById(R.id.incident_desc);
	mIncidentDesc.setOnFocusChangeListener(new View.OnFocusChangeListener()
	{

	    public void onFocusChange(View v, boolean hasFocus)
	    {
		if (!hasFocus)
		{
		    if (TextUtils.isEmpty(mIncidentDesc.getText()))
		    {
			mIncidentDesc
			        .setError(getString(R.string.empty_report_description));
		    }
		}
	    }

	});

	mContactInformation = (EditText) findViewById(R.id.incident_contact);
		
	findButton.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		Bundle flagBundle = new Bundle();
		// setLocationBySearch(mIncidentLocation.getText().toString());
		// han change query into a new activity, let users to change
		// address
		// pass a flag para to child activity
		// then it knows which father activity to return to
		// and pass the location name user entered
		// to child activity
		flagBundle.putString("locationName", mIncidentLocation
		        .getText().toString());
		Intent intent = new Intent();
		intent.putExtras(flagBundle);
		intent.setClass(IProvide.this, ChangeLoc.class);
		startActivityForResult(intent, REQUEST_CODE_CHANGE_LOC);
		setResult(RESULT_OK);
	    }
	});

	mBtnSend.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		// Check fields
		// Dipo Fix
		mError = false;
		if (TextUtils.isEmpty(mIncidentTitle.getText()))
		{
		    mErrorMessage = getString(R.string.empty_report_title);
		    mError = true;
		}

		if (TextUtils.isEmpty(mIncidentDesc.getText()))
		{
		    mErrorMessage += getString(R.string.empty_report_description);
		    mError = true;
		}

		/*
	         * if (TextUtils.isEmpty(mIncidentLocation.getText())) {
	         * mErrorMessage += getString(R.string.empty_report_location);
	         * mError = true; }
	         */

		// Oceanmaster: Don't check location field, because it will be
		// appointed on map
		if (sLatitude == 0.0 && sLongitude == 0.0)
		{
		    if (currentLatitude == 0.0 && currentLongitude == 0.0)
		    {
			mErrorMessage += getString(R.string.unable_to_locate_by_gps);
			mError = true;
		    }
		    else
		    {
			sLatitude = currentLatitude;
			sLongitude = currentLongitude;
			sLocationName = "Current Location";
		    }
		}
		// Dipo Fix
		if (mVectorCategories.size() == 0)
		{
		    mErrorMessage += getString(R.string.empty_report_categories);
		    mError = true;
		}

		// TODO configure category to default : Resource

		if (!mError)
		{
		    AlertDialog.Builder builder = new AlertDialog.Builder(
			    IProvide.this);
		    builder.setMessage("Are you sure to post it on line?")
			    .setCancelable(false)
			    .setPositiveButton("Yes",
			            new DialogInterface.OnClickListener()
			            {
			                public void onClick(
			                        DialogInterface dialog, int id)
			                {
				            AddReportsTask addReportsTask = new AddReportsTask();
				            addReportsTask.appContext = IProvide.this;
				            addReportsTask.execute();
			                }
			            })
			    .setNegativeButton("No",
			            new DialogInterface.OnClickListener()
			            {
			                public void onClick(
			                        DialogInterface dialog, int id)
			                {
				            dialog.cancel();
			                }
			            });
		    AlertDialog alert = builder.create();
		    alert.show();

		}
		else
		{
		    final Toast t = Toast.makeText(IProvide.this, "Error!\n\n"
			    + mErrorMessage, Toast.LENGTH_LONG);
		    t.show();
		    mErrorMessage = "";
		}

	    }
	});

	mBtnPicture.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		if (!TextUtils.isEmpty(UshahidiPref.resourceFileName))
		{
		    ImageManager.deleteImage(UshahidiPref.resourceFileName);
		}
		showDialog(DIALOG_CHOOSE_IMAGE_METHOD);
	    }
	});

	mBtnCancel.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		clearFields();
		// house keeping
		// ((LocationManager)
		// getSystemService(Context.LOCATION_SERVICE))
		// .removeUpdates(new DeviceLocationListener());
		// unregisterListeners();

		Intent intent = new Intent(IProvide.this, Ushahidi.class);
		startActivityForResult(intent, GOTOHOME);
		setResult(RESULT_OK);
		finish();
	    }
	});

	mBtnAddCategory.setOnClickListener(new View.OnClickListener()
	{
	    public void onClick(View v)
	    {
		showDialog(DIALOG_MULTIPLE_CATEGORY);
		mCounter++;
	    }
	});

	// mPickDate.setOnClickListener(new View.OnClickListener()
	// {
	//
	// public void onClick(View v)
	// {
	// showDialog(DATE_DIALOG_ID);
	// }
	// });

	// mPickTime.setOnClickListener(new View.OnClickListener()
	// {
	//
	// public void onClick(View v)
	// {
	// showDialog(TIME_DIALOG_ID);
	// }
	// });

	final Calendar c = Calendar.getInstance();
	mYear = c.get(Calendar.YEAR);
	mMonth = c.get(Calendar.MONTH);
	mDay = c.get(Calendar.DAY_OF_MONTH);
	mHour = c.get(Calendar.HOUR_OF_DAY);
	mMinute = c.get(Calendar.MINUTE);
	c.get(Calendar.AM_PM);
	updateDisplay();
	// Log.v("Oceanmaster","current time is"+mHour+":"+mMinute);

    }

    // fetch categories
    public String[] showCategories()
    {
	// TODO MUST change here!!!
	Cursor cursor = UshahidiApplication.mDb.fetchResourceCategories();

	// check if there are any existing categories in the database
	int categoryCount = cursor.getCount();
	int categoryAmount = 0;
	if (categoryCount > 0)
	{
	    categoryAmount = categoryCount;
	}
	else
	{
	    categoryAmount = 1;
	}

	String categories[] = new String[categoryAmount];

	int i = 0;
	if (cursor.moveToFirst())
	{

	    int titleIndex = cursor
		    .getColumnIndexOrThrow(UshahidiDatabase.CATEGORY_TITLE);

	    int idIndex = cursor
		    .getColumnIndexOrThrow(UshahidiDatabase.CATEGORY_ID);

	    do
	    {
		// TODO Don't understand
		categories[i] = cursor.getString(titleIndex);
		mCategoriesTitle.put(String.valueOf(cursor.getInt(idIndex)),
		        cursor.getString(titleIndex));
		mCategoriesId.add(String.valueOf(cursor.getInt(idIndex)));
		i++;
	    }
	    while (cursor.moveToNext());
	}

	// sets category to be on the phone from the beginning if there aren't
	// any already
	if (mCategoriesId.isEmpty())
	{
	    categories[0] = UNCATEGORIZED_CATEGORY_TITLE;
	    mCategoriesId.add(UNCATEGORIZED_CATEGORY_ID);
	    mCategoriesTitle.put(UNCATEGORIZED_CATEGORY_ID,
		    UNCATEGORIZED_CATEGORY_TITLE);
	}

	cursor.close();
	return categories;

    }

    // reset records in the field
    private void clearFields()
    {
	mBtnPicture = (Button) findViewById(R.id.btnPicture);
	// mBtnAddCategory = (Button) findViewById(R.id.add_category);
	mIncidentTitle.setText("");
	mIncidentLocation.setText("");
	mIncidentDesc.setText("");
	mContactInformation.setText("");
	// mVectorCategories.clear();
	mSelectedCategories.setText("");
	mSelectedPhoto.setImageDrawable(null);
	mSelectedPhoto.setImageBitmap(null);
	mCounter = 0;
	updateDisplay();

	// clear persistent data
	SharedPreferences.Editor editor = getPreferences(0).edit();
	editor.putString("title", "");
	// editor.putString("desc", ""); //TODO recover when descripton is
	// needed
	editor.putString("date", "");
	editor.commit();

    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data)
    {
	super.onActivityResult(requestCode, resultCode, data);
	// The preferences returned if the request code is what we had given
	// earlier in startSubActivity
	switch (requestCode)
	{

	    case REQUEST_CODE_CAMERA:
		if (resultCode != RESULT_OK)
		{
		    return;
		}

		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
		mBundle = null;
		mExtras = data.getExtras();
		if (mExtras != null)
		    mBundle = mExtras.getBundle("filename");

		if (mBundle != null && !mBundle.isEmpty())
		{
		    UshahidiPref.resourceFileName = mBundle.getString("name");
		    
		    Bitmap b_c=ImageManager.getBitmap(UshahidiPref.resourceFileName);
			ByteArrayOutputStream byteArrayos_c = new ByteArrayOutputStream();

			try
			{
			    b_c.compress(CompressFormat.JPEG, 75, byteArrayos_c);
			    byteArrayos_c.flush();
			}
			catch (OutOfMemoryError e)
			{

			    break;
			}
			catch (IOException e)
			{

			    break;
			}

		    mFilename = "android_pic_upload" + randomString() + ".jpg";
			ImageManager.writeImage(byteArrayos_c.toByteArray(), mFilename);
			UshahidiPref.resourceFileName = mFilename;
		    mSelectedPhoto.setImageBitmap(ImageManager
			    .getBitmap(UshahidiPref.resourceFileName));
		    mSelectedPhoto
			    .setScaleType(ImageView.ScaleType.CENTER_CROP);
		}
		break;

	    case REQUEST_CODE_IMAGE:

		if (resultCode != RESULT_OK)
		{
		    return;
		}

		Uri uri = data.getData();
		Bitmap b = null;

		try
		{
		    b = MediaStore.Images.Media.getBitmap(
			    this.getContentResolver(), uri);
		}
		catch (FileNotFoundException e)
		{
		    break;
		}
		catch (IOException e)
		{
		    break;
		}

		ByteArrayOutputStream byteArrayos = new ByteArrayOutputStream();

		try
		{
		    b.compress(CompressFormat.JPEG, 75, byteArrayos);
		    byteArrayos.flush();
		}
		catch (OutOfMemoryError e)
		{
		    break;
		}
		catch (IOException e)
		{
		    break;
		}

		mFilename = "android_pic_upload" + randomString() + ".jpg";
		ImageManager.writeImage(byteArrayos.toByteArray(), mFilename);
		UshahidiPref.resourceFileName = mFilename;

		mSelectedPhoto.setImageBitmap(ImageManager
		        .getBitmap(UshahidiPref.resourceFileName));
		mSelectedPhoto.setScaleType(ImageView.ScaleType.CENTER_CROP);
		break;

	    case VIEW_MAP:
		if (resultCode != RESULT_OK)
		{
		    return;
		}

		mBundle = null;
		mExtras = data.getExtras();
		if (mExtras != null)
		    mBundle = mExtras.getBundle("locations");

		if (mBundle != null && !mBundle.isEmpty())
		{
		    mIncidentLocation.setText(mBundle.getString("location"));

		    IProvide.sLatitude = mBundle.getDouble("latitude");
		    IProvide.sLongitude = mBundle.getDouble("longitude");
		}
		break;
	    // ----------------------------
	    // han add the case when back from changeloc child activity
	    // -------------------------
	    case REQUEST_CODE_CHANGE_LOC:
		if (resultCode == RESULT_OK)
		{
		    Bundle bundleForChangedLocation = new Bundle();
		    bundleForChangedLocation = data.getExtras();
		    if (bundleForChangedLocation != null)
		    {

			String locationName = String
			        .valueOf(bundleForChangedLocation
			                .get("locationName"));
			if (locationName != null)
			{
			    sLatitude = Double.valueOf(bundleForChangedLocation
				    .getString("Latitude"));
			    sLongitude = Double
				    .valueOf(bundleForChangedLocation
				            .getString("Longitude"));
			    sLocationName = locationName.substring(0);
			    // placeMarker((int)(sLatitude*1000000),
			    // (int)(sLongitude*1000000));
			    // centerLocation(getPoint(sLatitude,
			    // sLongitude),false);
			    // mReportLocation.setText(String.valueOf(sLatitude)
			    // + ", "
			    // + String.valueOf(sLongitude));
			    mIncidentLocation.setText(sLocationName);
			}
			else
			{
			    sLatitude = 0.0;
			    sLongitude = 0.0;
			    sLocationName = "";
			}
		    }
		    Log.v("Oceanmaster", "received location is:"
			    + sLocationName + "(" + sLatitude + ", "
			    + sLongitude + ")");
		}
		break;

	}
    }

    private static Random random = new Random();

    protected static String randomString()
    {
	return Long.toString(random.nextLong(), 10);
    }

    //
    final Runnable mSentIncidentOffline        = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       // TODO See this!!!
		                                       if (addToDb() == -1)
		                                       {
		                                           mHandler.post(mSentIncidentOfflineFail);
		                                       }
		                                       else
		                                       {
		                                           mHandler.post(mSentIncidentOfflineSuccess);
		                                           // clearFields();
		                                       }
	                                           }
	                                       };

    final Runnable mSentIncidentOfflineFail    = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               IProvide.this,
		                                               R.string.failed_to_add_report_offline);
	                                           }
	                                       };

    final Runnable mSentIncidentOfflineSuccess = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               IProvide.this,
		                                               R.string.report_successfully_added_offline);

	                                           }
	                                       };

    //
    final Runnable mSendIncidentOnline         = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       // TODO See this!!!!
		                                       if (!postToOnline())
		                                       {
		                                           mHandler.post(mSentIncidentFail);
		                                       }
		                                       else
		                                       {
		                                           mHandler.post(mSentIncidentSuccess);

		                                       }
	                                           }
	                                       };

    //
    final Runnable mSentIncidentSuccess        = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               IProvide.this,
		                                               R.string.report_successfully_added_online);

	                                           }
	                                       };

    final Runnable mSentIncidentFail           = new Runnable()
	                                       {
	                                           public void run()
	                                           {
		                                       Util.showToast(
		                                               IProvide.this,
		                                               R.string.failed_to_add_report_online);
	                                           }
	                                       };

    // ==============================
    // = Dialogs =
    // ==============================
    @Override
    protected Dialog onCreateDialog(int id)
    {
	switch (id)
	{
	    case DIALOG_ERROR_NETWORK:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.network_error));
		dialog.setMessage(getString(R.string.network_error_msg));
		dialog.setButton2(getString(R.string.btn_ok),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });
		dialog.setCancelable(false);
		return dialog;
	    }
	    case DIALOG_ERROR_SAVING:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.network_error));
		dialog.setMessage(getString(R.string.file_system_error_msg));
		dialog.setButton2(getString(R.string.btn_ok),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });
		dialog.setCancelable(false);
		return dialog;
	    }
	    case DIALOG_CHOOSE_IMAGE_METHOD:
	    {
		AlertDialog dialog = (new AlertDialog.Builder(this)).create();
		dialog.setTitle(getString(R.string.choose_method));
		dialog.setMessage(getString(R.string.how_to_select_pic));
		dialog.setButton(getString(R.string.gallery_option),
		        new Dialog.OnClickListener()
		        {
			    // TODO
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        Intent intent = new Intent();
			        intent.setAction(Intent.ACTION_PICK);
			        intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
			        Log.v("Oceanmaster",
			                "Gallery Image Path Selected");
			        startActivityForResult(intent,
			                REQUEST_CODE_IMAGE);
			        dialog.dismiss();
			    }
		        });
		dialog.setButton2(getString(R.string.btn_cancel),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {
			        dialog.dismiss();
			    }
		        });

		dialog.setButton3(getString(R.string.camera_option),
		        new Dialog.OnClickListener()
		        {
			    public void onClick(DialogInterface dialog,
			            int which)
			    {

			        Intent launchPreferencesIntent = new Intent()
			                .setClass(IProvide.this,
			                        ImageCapture.class);

			        // Make it a subactivity so we know when it
			        // returns
			        startActivityForResult(launchPreferencesIntent,
			                REQUEST_CODE_CAMERA);
			        dialog.dismiss();

			    }
		        });

		dialog.setCancelable(false);
		return dialog;

	    }
		// case DIALOG_CHOOSE_IMAGE_METHOD:
		// {
		// AlertDialog dialog = (new
		// AlertDialog.Builder(this)).create();
		// dialog.setTitle(getString(R.string.choose_method));
		// dialog.setMessage(getString(R.string.how_to_select_pic));
		// dialog.setButton(getString(R.string.gallery_option),
		// new Dialog.OnClickListener()
		// {
		//
		// public void onClick(DialogInterface dialog,
		// int which)
		// {
		// Intent intent = new Intent();
		// intent.setAction(Intent.ACTION_PICK);
		// intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		// startActivityForResult(intent,
		// REQUEST_CODE_IMAGE);
		// dialog.dismiss();
		// }
		// });
		// dialog.setButton2(getString(R.string.btn_cancel),
		// new Dialog.OnClickListener()
		// {
		// public void onClick(DialogInterface dialog,
		// int which)
		// {
		// dialog.dismiss();
		// }
		// });
		//
		// dialog.setButton3(getString(R.string.camera_option),
		// new Dialog.OnClickListener()
		// {
		// public void onClick(DialogInterface dialog,
		// int which)
		// {
		//
		// Intent launchPreferencesIntent = new Intent()
		// .setClass(IProvide.this,
		// ImageCapture.class);
		//
		// // Make it a subactivity so we know when it
		// // returns
		// startActivityForResult(launchPreferencesIntent,
		// REQUEST_CODE_CAMERA);
		// dialog.dismiss();
		//
		// }
		// });
		//
		// dialog.setCancelable(false);
		// return dialog;
		//
		// }

	    case DIALOG_MULTIPLE_CATEGORY:
	    {
		return new AlertDialog.Builder(this)
		        .setTitle(R.string.add_categories)
		        .setMultiChoiceItems(
		                showCategories(),// TODO !! change to Resource
		                                 // Categories
		                null,
		                new DialogInterface.OnMultiChoiceClickListener()
		                {
			            public void onClick(DialogInterface dialog,
			                    int whichButton, boolean isChecked)
			            {

			                if (isChecked)
			                {
				            mVectorCategories.add(mCategoriesId
				                    .get(whichButton));
				            // put together
				            // if (!mVectorCategories.isEmpty())
				            // {
				            // mSelectedCategories.setText(
				            // Util.limitString(
				            // //
				            // mCategoriesTitle.get(mVectorCategories.get(0)),
				            // Util.implode(getCategoriesByIds(mVectorCategories)),
				            // 15));
				            // }

				            mError = false;
			                }
			                else
			                {
				            // fixed a crash here.
				            mVectorCategories
				                    .remove(mCategoriesId
				                            .get(whichButton));
				            // put down together
				            // if (mVectorCategories.isEmpty())
				            // {
				            // mSelectedCategories.setText("");
				            // }
				            // else
				            // {
				            // mSelectedCategories.setText(
				            // Util.limitString(
				            // //mCategoriesTitle.get(mVectorCategories.get(0)),
				            // Util.implode(getCategoriesByIds(mVectorCategories)),
				            // 15));
				            // }
			                }

			            }
		                })
		        .setPositiveButton(R.string.btn_ok,
		                new DialogInterface.OnClickListener()
		                {
			            public void onClick(DialogInterface dialog,
			                    int whichButton)
			            {

			                /* User clicked Yes so do some stuff */

			                Log.v("Oceanmaster",
			                        "mVectorCategories is ["
			                                + Util.implode(mVectorCategories)
			                                + "]");
			                Log.v("Oceanmaster",
			                        "getCategoriesByIds is ["
			                                + Util.implode(getCategoriesByIds(mVectorCategories))
			                                + "]");
			                if (mVectorCategories.isEmpty())
			                {
				            mSelectedCategories.setText("");
			                }
			                else
			                {
				            mSelectedCategories.setText(Util.limitString(
				                    // mCategoriesTitle.get(mVectorCategories.get(0)),
				                    Util.implode(getCategoriesByIds(mVectorCategories)),
				                    30));
			                }
			            }
		                }).create();
	    }

		// case TIME_DIALOG_ID:
		// return new TimePickerDialog(this, mTimeSetListener, mHour,
		// mMinute, false);
		//
		// case DATE_DIALOG_ID:
		// return new DatePickerDialog(this, mDateSetListener, mYear,
		// mMonth, mDay);
	}
	return null;
    }

    // Time picker dialogs have to be prepared with current time every time it
    // is opened
    // @Override
    // protected void onPrepareDialog(int id, Dialog dialog)
    // {
    // switch (id)
    // {
    // case TIME_DIALOG_ID:
    // ((TimePickerDialog) dialog).updateTime(mHour, mMinute);
    // break;
    // case DATE_DIALOG_ID:
    // ((DatePickerDialog) dialog).updateDate(mYear, mMonth, mDay);
    // break;
    // }
    // }

    // used by updateDisplay()
    private static String pad(int c)
    {
	if (c >= 10)
	    return String.valueOf(c);
	else
	    return "0" + String.valueOf(c);
    }

    private void initTimeDigit()
    {
	mTimeDigits = new HashMap<Integer, Integer>();

	mTimeDigits.put(00, 12);
	mTimeDigits.put(13, 1);
	mTimeDigits.put(14, 2);
	mTimeDigits.put(15, 3);
	mTimeDigits.put(16, 4);
	mTimeDigits.put(17, 5);
	mTimeDigits.put(18, 6);
	mTimeDigits.put(19, 7);
	mTimeDigits.put(20, 8);
	mTimeDigits.put(21, 9);
	mTimeDigits.put(22, 10);
	mTimeDigits.put(23, 11);
	mTimeDigits.put(24, 12);
	mTimeDigits.put(12, 12);
	mTimeDigits.put(1, 1);
	mTimeDigits.put(2, 2);
	mTimeDigits.put(3, 3);
	mTimeDigits.put(4, 4);
	mTimeDigits.put(5, 5);
	mTimeDigits.put(6, 6);
	mTimeDigits.put(7, 7);
	mTimeDigits.put(8, 8);
	mTimeDigits.put(9, 9);
	mTimeDigits.put(10, 10);
	mTimeDigits.put(11, 11);
	mTimeDigits.put(12, 12);
    }

    private void updateDisplay()
    {
	if (mTimeDigits == null)
	    initTimeDigit();
	String amPm;
	if (mHour >= 12)
	    amPm = "PM";
	else
	    amPm = "AM";

	String strDate = new StringBuilder()

	        // Month is 0 based so add 1
	        .append(mYear).append("-").append(pad(mMonth + 1)).append("-")
	        .append(pad(mDay)).toString();

	String dateTime = Util.formatDate("yyyy-MM-dd", strDate,
	        "MMMM dd, yyyy");

	// mIncidentDate.setText(dateTime + " at " + pad(mTimeDigits.get(mHour))
	// + ":" + pad(mMinute) + " " + amPm);

	mDateToSubmit = new StringBuilder()
	        // Month is 0 based so add 1
	        .append(pad(mMonth + 1)).append("/").append(pad(mDay))
	        .append("/").append(mYear).append(" ").append(pad(mHour))
	        .append(":").append(pad(mMinute)).append(" ").append(amPm)
	        .toString();

	Log.v("Oceanmaster", "" + mDateToSubmit);
    }

    // private DatePickerDialog.OnDateSetListener mDateSetListener = new
    // DatePickerDialog.OnDateSetListener()
    // {
    //
    // public void onDateSet(
    // DatePicker view,
    // int year,
    // int monthOfYear,
    // int dayOfMonth)
    // {
    // mYear = year;
    // mMonth = monthOfYear;
    // mDay = dayOfMonth;
    // updateDisplay();
    // }
    // };
    //
    // private TimePickerDialog.OnTimeSetListener mTimeSetListener = new
    // TimePickerDialog.OnTimeSetListener()
    // {
    //
    // public void onTimeSet(
    // TimePicker view,
    // int hourOfDay,
    // int minute)
    // {
    // mHour = hourOfDay;
    // mMinute = minute;
    //
    // updateDisplay();
    // }
    // };

    /**
     * Insert incident data into db when app is offline.
     * 
     * @author henryaddo
     */
    public long addToDb()
    {
	// TODO Watch here!!
	String dates[] = mDateToSubmit.split(" ");
	String time[] = dates[1].split(":");

	List<AddIncidentData> addIncidentsData = new ArrayList<AddIncidentData>();

	AddIncidentData addIncidentData = new AddIncidentData();
	addIncidentsData.add(addIncidentData);

	addIncidentData.setIncidentTitle(mIncidentTitle.getText().toString());
	addIncidentData.setIncidentDesc(mIncidentDesc.getText().toString());// TODO
	addIncidentData.setContactInformation(mContactInformation.getText().toString());
	
	// Recovery when needed
	addIncidentData.setIncidentDate(dates[0]);
	addIncidentData.setIncidentHour(Integer.parseInt(time[0]));
	addIncidentData.setIncidentMinute(Integer.parseInt(time[1]));
	addIncidentData.setIncidentAmPm(dates[2].toLowerCase());

	// TODO set category to resource here
	// addIncidentData.setIncidentCategories(Util.implode(mVectorCategories));
	addIncidentData.setIncidentLocName(sLocationName);
	addIncidentData.setIncidentLocLatitude(String.valueOf(sLatitude));
	addIncidentData.setIncidentLocLongitude(String.valueOf(sLongitude));
	addIncidentData.setIncidentPhoto(UshahidiPref.resourceFileName);
	addIncidentData.setPersonFirst(UshahidiPref.firstname);
	addIncidentData.setPersonLast(UshahidiPref.lastname);
	addIncidentData.setPersonEmail(UshahidiPref.email);

	// add it to database.
	return UshahidiApplication.mDb.addIncidents(addIncidentsData);
    }

    /**
     * Post directly to online.
     * 
     * @author henryaddo
     */
    public boolean postToOnline()
    {
	// TODO watch here!!
	if (TextUtils.isEmpty(UshahidiPref.domain)
	        || UshahidiPref.domain.equalsIgnoreCase("http://"))
	{
	    return false;
	}

	String dates[] = mDateToSubmit.split(" ");
	String time[] = dates[1].split(":");
	// TODO set category to resource here
	String categories = Util.implode(mVectorCategories);

	StringBuilder urlBuilder = new StringBuilder(UshahidiPref.domain);
	urlBuilder.append("/api");

	mParams.put("task", "resource");
	mParams.put("resource_title", mIncidentTitle.getText().toString());
	mParams.put("resource_description", mIncidentDesc.getText().toString());
	mParams.put("resource_contact", mContactInformation.getText().toString());
	mParams.put("resource_date", dates[0]);
	mParams.put("resource_hour", time[0]);
	mParams.put("resource_minute", time[1]);
	mParams.put("resource_ampm", dates[2].toLowerCase());
	mParams.put("resource_category", categories);
	mParams.put("latitude", String.valueOf(sLatitude));
	mParams.put("longitude", String.valueOf(sLongitude));
	mParams.put("location_name", sLocationName);
	mParams.put("person_first", UshahidiPref.firstname);
	mParams.put("person_last", UshahidiPref.lastname);
	mParams.put("person_email", UshahidiPref.email);
	mParams.put("filename", UshahidiPref.resourceFileName);

	try
	{
	    return UshahidiHttpClient.PostFileUpload(urlBuilder.toString(),
		    mParams);
	}
	catch (IOException e)
	{
	    e.printStackTrace();
	    return false;
	}

    }

    public void onClickHome(View v)
    {
	goHome(this);
    }

    /**
     * Go back to the home activity.
     * 
     * @param context
     *            Context
     * @return void
     */

    public void goHome(Context context)
    {
	final Intent intent = new Intent(context, Ushahidi.class);
	intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
	context.startActivity(intent);
    }

    public void onSearchDeployments(View v)
    {
	// TODO Change HERE!!!!!
	Intent intent = new Intent(IProvide.this, DeploymentSearch.class);
	startActivityForResult(intent, VIEW_SEARCH);
	setResult(RESULT_OK);
    }

    /**
     * Sets nVectorCategories
     * 
     * @param aVectorCategories
     */
    public void setVectorCategories(Vector<String> aVectorCategories)
    {
	mVectorCategories = aVectorCategories;
    }

    // thread class
    // TODO Main Logic On Submitting!!
    private class AddReportsTask extends AsyncTask<Void, Void, Integer>
    {

	protected Integer status;
	private ProgressDialog dialog;
	protected Context appContext;

	@Override
	protected void onPreExecute()
	{
	    //refreshState = true;
	    //updateRefreshStatus();
	    this.dialog = ProgressDialog.show(appContext,
		    getString(R.string.please_wait),
		    getString(R.string.posting_new_reports), true);
		// thread for displaying the SplashScreen
		Thread progressBarTread = new Thread()
		{
		    @Override
		    public void run()
		    {
			try
			{
				sleep(1000);
			}
			catch (InterruptedException e)
			{
			    // do nothing
			}
		    }
		};
		progressBarTread.start();

	    //setProgressBarIndeterminateVisibility(true);

	}

	@Override
	protected Integer doInBackground(Void... mParams)
	{
	    // =================TODO Notice TODO===================
	    // Main Logic here:
	    // First, try to submit online
	    // If failed, store in database temporarily
	    // status = 0 Success
	    // status = 1 Submit Online Fail
	    // status = 2 No Internet Access, Fail directly
	    // Data will be stored in database automatically when 1 or 2
	    // ========================================
	    if (Util.isConnected(IProvide.this))
	    {

		if (!postToOnline())
		{
		    addToDb();
		    status = 1; // fail
		}
		else
		{
		    status = 0; // success
		}
	    }
	    else
	    {
		addToDb();
		status = 2; // no internet connection
	    }
	    return status;
	}

	@Override
	protected void onPostExecute(Integer result)
	{
	    // TODO !!!!!
	    // I plan to change business logic here
	    // if success, go home
	    // else return to page
	    // however, this may cause lots of same data in DB....
		this.dialog.cancel();
	    if (result == 2)
	    {
		clearFields();
		Util.showToast(appContext,
		        R.string.report_successfully_added_offline);
		// -----------------------------------
		// need to test the time needed to keep the device asleep
		// to make it jump to main page smoothly
		// --------------------------------
		try
		{
		    Thread.sleep(1000);
		}
		catch (InterruptedException e)
		{
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
		goHome(appContext);
	    }
	    else if (result == 1)
	    {
		clearFields();
		Util.showToast(appContext, R.string.failed_to_add_report_online);
	    }
	    else if (result == 0)
	    {
		clearFields();
		// after a successful upload, delete the file
		File f = new File(UshahidiPref.savePath
		        + UshahidiPref.resourceFileName);
		if (f.exists())
		{
		    f.delete();
		}
		Util.showToast(appContext,
		        R.string.report_successfully_added_online);

		// -----------------------------------
		// need to test the time needed to keep the device asleep
		// to make it jump to main page smoothly
		// --------------------------------
		try
		{
		    Thread.sleep(1000);
		}
		catch (InterruptedException e)
		{
		    // TODO Auto-generated catch block
		    e.printStackTrace();
		}
		goHome(appContext);
	    }
	    setProgressBarIndeterminateVisibility(false);
	}
    }

    private Vector<String> getCategoriesByIds(Vector<String> ids)
    {
	Vector<String> cates = new Vector<String>();
	for (String id : ids)
	{
	    if (mCategoriesTitle.containsKey(id))
		cates.add(mCategoriesTitle.get(id));
	}
	return cates;
    }
}
